package com.walking.ds;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * @author walking
 * 公众号：编程大道
 */
public class DynamicDataSourceRoutingAspect {

    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("进入AOP环绕通知");
        Signature signature = joinPoint.getSignature();
        String datasourceName = getDatasourceKey(signature);
        System.out.println("--------\n当前使用数据源："+datasourceName+"\n------");
        if (StringUtils.hasText(datasourceName)) {
            DynamicDataSource.setDataSourceName(datasourceName);
        }
        return joinPoint.proceed();
    }

    private String getDatasourceKey(Signature signature) {
        if (signature == null) {
            return null;
        } else {
            if (signature instanceof MethodSignature) {
                MethodSignature methodSignature = (MethodSignature) signature;
                Method method = methodSignature.getMethod();
                if (method.isAnnotationPresent(DataSource.class)) {
                    return this.dsSettingInMethod(method);
                }
                Class<?> declaringClass = method.getDeclaringClass();
                if (declaringClass.isAnnotationPresent(DataSource.class)) {
                    return this.dsSettingInConstructor(declaringClass);
                }
                Package aPackage = declaringClass.getPackage();
                this.dsSettingInPackage(aPackage);
            }
            return null;
        }
    }

    private String dsSettingInConstructor(Class<?> declaringClass) {
        DataSource dataSource = declaringClass.getAnnotation(DataSource.class);
        return dataSource.value();
    }

    private String dsSettingInMethod(Method method) {
        DataSource dataSource = method.getAnnotation(DataSource.class);
        return dataSource.value();
    }
    private void dsSettingInPackage(Package aPackage){
        DynamicDataSource.usagePackageDataSource(aPackage.getName());
    }

}
